#ifndef SOFTWAREPWM_H
#define SOFTWAREPWM_H
#include "TimerEventQueue.h"
struct PWMParams
{
    unsigned short pin;
    unsigned long pulseLength;
    unsigned long minHigh;
    unsigned long maxHigh;
};
class Pwm : public TimerEventListener
{
public:
    Pwm(TimerQueue& ptimer, PWMParams par)
        :timer(ptimer),isHigh(false),params(par)
    {
           params.maxHigh = par.maxHigh==0?par.pulseLength:par.maxHigh;
    }
    unsigned long onTime()
    {
        if(isHigh)
        {
            digitalWrite(params.pin,LOW);
            isHigh = false;
            return lowTime;
        }
        else
        {
            digitalWrite(params.pin,HIGH);
            isHigh = true;
            return highTime;
        }
    }
    void setPWM(unsigned char val)
    {
        unsigned long highLen = params.maxHigh-params.minHigh;
        highTime = params.minHigh+(highLen*val)/255;
        lowTime = params.pulseLength - highTime;
        if(lowTime==0)//do not deregister on hightime=pulselengh
            lowTime = 1;
        if(highTime==0)//do not deregister on hightime=0
            highTime = 1;
    }
    void start()
    {
        lowTime = params.pulseLength - highTime;
        if( highTime != 0 )
            timer.registerTimerEvent(this,isHigh?lowTime:highTime);
    }
    void stop()
    {
        lowTime = 0;//0 will remove this object from timer queue, and leave the pin on LOW value
    }
private:
    TimerQueue& timer;
    bool isHigh;
    PWMParams params;
    unsigned long highTime, lowTime;

};

#endif // SOFTWAREPWM_H
